#include "bsp_gpio.h"


/*
 * @description 	: GPIO初始化。
 * @param - base 	: 要初始化的寄存器组。
 * @param - pin		: 要初始化的寄存器脚号。
 * @param - config	: GPIO 配置结构体。
 * @return 			: 无
 */
void gpio_init(GPIO_Type *base, int pin, gpio_pin_config_t *config)
{
	if(config)
	{
		if(config->directioin == kGPIO_DigitalOutput){
			base->GDIR |= (1<<pin);								/* 输出 */

			gpio_pinwrite(base, pin, config->outputLogic);		/* 默认输出电平 */
		}
		else if(config->directioin == kGPIO_DigitalInput){
			base->GDIR &= ~(1<<pin);							/* 输入 */
		}

		if(config->directioin == kGPIO_DigitalInput){
			gpio_intmode_config(base, pin, config->intMode);		/* gpio中断触发方式配置 */
		}
	}
}

/*
 * @description 	: 指定 GPIO 输出高或者低电平。
 * @param – base 	: 要输出的 GPIO 组。
 * @param – pin 	: 要输出的 GPIO 脚号。
 * @param - value	: 要输出的电平， 1 输出高电平， 0 输出低低电平
 * @return 			: 无
 */
void gpio_pinwrite(GPIO_Type *base, int pin, int value)
{
	if(value == 0)
		base->DR &= ~(1<<pin);
	else
		base->DR |= (1<<pin);
}

/*
 * @description 	: 读取指定 GPIO 的电平值。
 * @param – base 	: 要读取的 GPIO 组。
 * @param – pin 	: 要读取的 GPIO 脚号。
 * @return 			: 1 读取高电平， 0 读取低低电平。
 */
int  gpio_pinread(GPIO_Type *base, int pin)
{
	return ((base->DR >> pin) & 0x1);
}

/*
 * @description 	: 启用GPIO指定pin的中断。
 * @param – base 	: 要启用的 GPIO 组。
 * @param – pin 	: 要启用的 GPIO 脚号。
 * @return 			: 无。
 */
void gpio_int_enable(GPIO_Type *base, int pin)
{
	base->IMR |= (1 << pin);
}

/*
 * @description 	: 禁用GPIO指定pin的中断。
 * @param – base 	: 要禁用的 GPIO 组。
 * @param – pin 	: 要启用中断的 GPIO 脚号。
 * @return 			: 无。
 */
void gpio_int_disable(GPIO_Type *base, int pin)
{
	base->IMR &= ~(1 << pin);
}

/*
 * @description 	: 清除GPIO指定pin的中断标志。
 * @param – base 	: 要清除的 GPIO 组。
 * @param – pin 	: 要清除中断的 GPIO 脚号。
 * @return 			: 无。
 */
void gpio_int_cleanFlag(GPIO_Type *base, int pin)
{
	/* 写1清除对应的中断标志位 */
	base->ISR |= (1 << pin);
}

/*
 * @description 	: 设置GPIO中断触发类型。
 * @param – base 	: 要清除的 GPIO 组。
 * @param – pin 	: 要清除中断的 GPIO 脚号。
 * @return 			: 无。
 */
void gpio_intmode_config(GPIO_Type *base, int pin, gpio_int_mode_t mode)
{
	volatile unsigned int *icr;			/* volatile关键字要求立即写入内存，不要在寄存器中缓存 */
	unsigned int icrShift = pin;

	if(pin < 16)
	{
		icr = &base->ICR1;

	}
	else{
		icr = &base->ICR2;
		icrShift -= 16;
	}

	//我忘记了清理GPIO1->EDGESEL寄存器的对应pin
	base->EDGE_SEL &= ~(1 << pin);
	
	*icr &= ~(0x3 << (icrShift * 2));	/* 清零gpio->ICR 寄存器对应的位 */

	switch(mode)
	{
		case kGPIO_Noint:
			break;
		case kGPIO_LowInterrupt:
			*icr |= (0 << (icrShift * 2));
			break;
		case kGPIO_HighInterrupt:
			*icr |= (1 << (icrShift * 2));
			break;
		case kGPIO_RaisingEdgeInt:
			*icr |= (2 << (icrShift * 2));
			break;
		case kGPIO_FalllingEdgeInt:
			*icr |= (3 << (icrShift * 2));
			break;
		case kGPIO_FallingOrRaisingEdgeInt:
			base->EDGE_SEL |= (1 << pin);
			break;
	}
}